from flask import Blueprint, request, current_app, render_template, redirect, url_for, flash, session, g
import random
from flask_mail import Message
from exts import mail, cache, db
from utils import restful
from forms.user import RegisterForm, LoginForm, EditProfileForm
from models.user import UserModel
from decorators import login_required
from werkzeug.datastructures import CombinedMultiDict
from werkzeug.utils import secure_filename
import os

bp = Blueprint("user", __name__, url_prefix="/user")


# 获取邮箱验证码
@bp.route("/mail/captcha")
def mail_captcha():
    try:
        # 修改参数名为 mail，与前端保持一致
        email = request.args.get("mail")
        if not email:
            return restful.params_error(message="请传入邮箱地址！")
        
        digits = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
        # random.sample(digits, 4)返回的是列表类型
        captcha = "".join(random.sample(digits, 4))
        body = f"【Pyhton论坛】您的注册验证码是：{captcha}，请勿告诉别人！"
        subject = "发送邮箱验证码"
        message = Message(subject=subject, recipients=[email], body=body)
        mail.send(message)
        # current_app.celery.send_task("send_mail",(email,subject,body))
        cache.set(email, captcha, timeout=100)
        return restful.ok()
    except Exception as e:
        # 记录详细错误信息到日志
        current_app.logger.error(f"发送验证码失败: {str(e)}", exc_info=True)
        return restful.server_error(message=f"发送验证码失败：{str(e)}")


# 注册
@bp.route("/register", methods=["POST", "GET"])
def register():
    if request.method == "GET":
        return render_template("front/register.html")
    else:
        form = RegisterForm(request.form)
        if form.validate():
            email = form.email.data
            username = form.username.data
            password = form.password.data
            user = UserModel(email=email, username=username, password=password)
            db.session.add(user)
            db.session.commit()
            return redirect(url_for("user.login"))
        else:
            for message in form.message:
                # 在用户界面上显示一次性消息的函数,在下一个请求中显示该消息
                flash(message)
            return redirect(url_for("user.register"))


# 登录
@bp.route("/login", methods=["POST", "GET"])
def login():
    if request.method == "GET":
        return render_template("front/login.html")
    else:
        form = LoginForm(request.form)
        if form.validate:
            email = form.email.data
            password = form.password.data
            remember = form.remember.data
            user = UserModel.query.filter_by(email=email).first()
            if user and user.check_password(password):
                if not user.is_active:
                    flash("该用户已被禁用！")
                    return redirect(url_for("user.login"))
                current_app.logger.debug(f"{email}用户成功登陆")
                session["user_id"] = user.id
                if remember:
                    session.permanent = True
                return redirect("/")
            else:
                flash("邮箱或密码错误！")
                return redirect(url_for("user.login"))
        else:
            for message in form.message:
                flash(message)
            return render_template("front/login.html")


# 根据user_id获取用户详情
@bp.get("/profile/<string:user_id>")
def profile(user_id):
    user = UserModel.query.get(user_id)
    is_mine = False
    if hasattr(g, "user") and g.user_id == user_id:
        is_mine = True
    context = {
        "user": user,
        "is_mine": is_mine
    }
    print(user)
    return render_template("front/profile.html", **context)


# 退出登录
@bp.get("/logout")
def logout():
    session.clear()
    return redirect("/")


# 修改用户信息
@bp.post("/profile/edit")
@login_required
def edit_profile():
    form = EditProfileForm(CombinedMultiDict([request.form, request.files]))
    if form.validate():
        username = form.username.data
        avatar = form.avatar.data
        signature = form.signature.data

        # 如果上传了头像
        if avatar:
            # 生成安全的文件名
            filename = secure_filename(avatar.filename)
            # 拼接头像存储路径
            avatar_path = os.path.join(current_app.config.get("AVATARS_SAVE_PATH"), filename)
            # 保存文件
            avatar.save(avatar_path)
            # 设置头像的url
            g.user.avatar = url_for("media.media_file", filename=os.path.join("avatars", filename))

        g.user.username = username
        g.user.signature = signature
        db.session.commit()
        return redirect(url_for("user.profile", user_id=g.user.id))
    else:
        for message in form.messages:
            flash(message)
        return redirect(url_for("user.profile", user_id=g.user.id))
